// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) definits fieldsfirst ansi space safe 
// Source File Name:   SimpleRigidBody.java

package jones.rigid;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Observable;

// Referenced classes of package jones.rigid:
//            ConvexPolygon, Attachable, RigidBody

public class SimpleRigidBody extends Observable
    implements RigidBody, Serializable
{

    private ConvexPolygon shape = null;
    private double front = 0;
    private double x = 0;
    private double y = 0;
    private double vx = 0;
    private double vy = 0;
    private double w = 0;
    private double axisX = 0;
    private double axisY = 0;
    private AffineTransform transform = null;
    private AffineTransform oldTransform = null;
    private boolean isRevertable = false;
    private boolean isPushable = false;
    private boolean isRelativeVelocity = false;
    private Point2D p = null;
    private AffineTransform t = null;
    private java.util.List attached = null;

    public SimpleRigidBody()
    {
        shape = new ConvexPolygon();
        front = 0.0D;
        x = 0.0D;
        y = 0.0D;
        vx = 0.0D;
        vy = 0.0D;
        w = 0.0D;
        axisX = 0.0D;
        axisY = 0.0D;
        transform = new AffineTransform();
        oldTransform = new AffineTransform();
        isRevertable = false;
        isPushable = false;
        isRelativeVelocity = true;
        p = ((Point2D) (new java.awt.geom.Point2D.Double()));
        t = new AffineTransform();
        attached = ((java.util.List) (new ArrayList()));
    }

    public SimpleRigidBody(ConvexPolygon shape, double x, double y, double front)
    {
        this.shape = new ConvexPolygon();
        this.front = 0.0D;
        this.x = 0.0D;
        this.y = 0.0D;
        vx = 0.0D;
        vy = 0.0D;
        w = 0.0D;
        axisX = 0.0D;
        axisY = 0.0D;
        transform = new AffineTransform();
        oldTransform = new AffineTransform();
        isRevertable = false;
        isPushable = false;
        isRelativeVelocity = true;
        p = ((Point2D) (new java.awt.geom.Point2D.Double()));
        t = new AffineTransform();
        attached = ((java.util.List) (new ArrayList()));
        this.shape.setPolygon(((Polygon) (shape)));
        this.x = x;
        this.y = y;
        this.front = front;
    }

    public SimpleRigidBody(SimpleRigidBody body)
    {
        shape = new ConvexPolygon();
        front = 0.0D;
        x = 0.0D;
        y = 0.0D;
        vx = 0.0D;
        vy = 0.0D;
        w = 0.0D;
        axisX = 0.0D;
        axisY = 0.0D;
        transform = new AffineTransform();
        oldTransform = new AffineTransform();
        isRevertable = false;
        isPushable = false;
        isRelativeVelocity = true;
        p = ((Point2D) (new java.awt.geom.Point2D.Double()));
        t = new AffineTransform();
        attached = ((java.util.List) (new ArrayList()));
        shape.setPolygon(((Polygon) (body.shape)));
        front = body.front;
        x = body.x;
        y = body.y;
        vx = body.vx;
        vy = body.vy;
        w = body.w;
        axisX = body.axisX;
        axisY = body.axisY;
        transform.setTransform(body.transform);
        oldTransform.setTransform(body.oldTransform);
        isRevertable = body.isRevertable;
        isPushable = body.isPushable;
        p.setLocation(body.p);
        t.setTransform(body.t);
    }

    public AffineTransform getCurrentTransform(AffineTransform transform)
    {
        if (transform == null)
            transform = new AffineTransform();
        transform.setTransform(this.transform);
        return transform;
    }

    public ConvexPolygon getShape(ConvexPolygon shape)
    {
        if (shape == null)
            shape = new ConvexPolygon();
        shape.setPolygon(((Polygon) (this.shape)));
        return shape;
    }

    public void setShape(ConvexPolygon shape)
    {
        this.shape.setPolygon(((Polygon) (shape)));
        setChanged();
    }

    public void setCenterOfMass(double x, double y)
    {
        this.x = x;
        this.y = y;
        setChanged();
    }

    public void setFront(double front)
    {
        this.front = front;
    }

    public ConvexPolygon getCurrentShape(ConvexPolygon currentShape)
    {
        if (currentShape == null)
            currentShape = new ConvexPolygon();
        currentShape.setPolygon(((Polygon) (shape)));
        currentShape.transform(transform);
        return currentShape;
    }

    public ConvexPolygon getPreviousShape(ConvexPolygon previousShape)
    {
        if (!isRevertable)
            return getCurrentShape(previousShape);
        if (previousShape == null)
            previousShape = new ConvexPolygon();
        previousShape.setPolygon(((Polygon) (shape)));
        previousShape.transform(oldTransform);
        return previousShape;
    }

    public double getLocationX()
    {
        p.setLocation(x, y);
        transform.transform(p, p);
        return p.getX();
    }

    public double getLocationY()
    {
        p.setLocation(x, y);
        transform.transform(p, p);
        return p.getY();
    }

    public void setLocation(double x, double y)
    {
        double orientation = getOrientation();
        transform.setToTranslation(x, y);
        setOrientation(orientation);
        updateAttached();
        setChanged();
    }

    public double getOrientation()
    {
        p.setLocation(this.x + Math.cos(front), this.y + Math.sin(front));
        transform.transform(p, p);
        double x = p.getX();
        double y = p.getY();
        return Math.atan2(y - getLocationY(), x - getLocationX());
    }

    public void setOrientation(double orientation)
    {
        transform.rotate(orientation - getOrientation(), x, y);
        updateAttached();
        setChanged();
    }

    public double getVelocityX()
    {
        return vx;
    }

    public double getVelocityY()
    {
        return vy;
    }

    public boolean isRelativeVelocity()
    {
        return isRelativeVelocity;
    }

    public void setVelocity(double vx, double vy)
    {
        if (isPushable)
        {
            return;
        } else
        {
            this.vx = vx;
            this.vy = vy;
            setChanged();
            return;
        }
    }

    public void setRelativeVelocity(boolean isRelativeVelocity)
    {
        this.isRelativeVelocity = isRelativeVelocity;
        setChanged();
    }

    public double getAngularVelocity()
    {
        return w;
    }

    public void setAngularVelocity(double angularVelocity)
    {
        if (isPushable)
        {
            return;
        } else
        {
            w = angularVelocity;
            setChanged();
            return;
        }
    }

    public double getAxisX()
    {
        p.setLocation(axisX, axisY);
        p = transform.transform(p, p);
        return p.getX();
    }

    public double getAxisY()
    {
        p.setLocation(axisX, axisY);
        p = transform.transform(p, p);
        return p.getY();
    }

    public void setAxis(double x, double y)
    {
        axisX = x;
        axisY = y;
        setChanged();
    }

    public void move(double time)
    {
        oldTransform.setTransform(transform);
        if (isRelativeVelocity)
        {
            transform.translate(vx * time, vy * time);
        } else
        {
            t.setToTranslation(vx * time, vy * time);
            transform.preConcatenate(t);
        }
        transform.rotate(w * time, axisX, axisY);
        updateAttached();
        isRevertable = true;
        setChanged();
    }

    public void push(RigidBody pusher, double time)
    {
        if (!isPushable)
            return;
        if (pusher.getAngularVelocity() != 0.0D)
            return;
        oldTransform.setTransform(transform);
        if (pusher.isRelativeVelocity())
        {
            double theta = getOrientation() - pusher.getOrientation();
            double rotation11 = Math.cos(theta);
            double rotation12 = Math.sin(theta);
            transform.translate((rotation11 * pusher.getVelocityX() + rotation12 * pusher.getVelocityY()) * time, (-rotation12 * pusher.getVelocityX() + rotation11 * pusher.getVelocityY()) * time);
        } else
        {
            t.setToTranslation(pusher.getVelocityX() * time, pusher.getVelocityY() * time);
            transform.preConcatenate(t);
        }
        updateAttached();
        isRevertable = true;
        setChanged();
    }

    public void revert()
    {
        if (isRevertable)
        {
            transform.setTransform(oldTransform);
            updateAttached();
            isRevertable = false;
            setChanged();
        }
    }

    public boolean isRevertable()
    {
        return isRevertable;
    }

    public boolean isPushable()
    {
        return isPushable;
    }

    public void setPushable(boolean isPushable)
    {
        this.isPushable = isPushable;
        if (isPushable)
        {
            vx = 0.0D;
            vy = 0.0D;
            w = 0.0D;
        }
    }

    public boolean isMoving()
    {
        return vx != 0.0D || vy != 0.0D || w != 0.0D;
    }

    public AffineTransform getTransform(AffineTransform transform)
    {
        if (transform == null)
            transform = new AffineTransform();
        transform.setTransform(this.transform);
        return transform;
    }

    public void attach(Attachable attachable)
    {
        attached.add(((Object) (attachable)));
        updateAttached();
        setChanged();
    }

    public void unattach(Attachable attachable)
    {
        attached.remove(((Object) (attachable)));
        setChanged();
    }

    private void updateAttached()
    {
        for (int i = 0; i < attached.size(); i++)
        {
            Attachable attachable = (Attachable)attached.get(i);
            attachable.setTransform(transform);
        }

    }

    public String toString()
    {
        return getCurrentShape(((ConvexPolygon) (null))) + "x=" + x + " y=" + y + "\n" + "vx=" + vx + " vy=" + vy + "\n" + "w=" + w + " axisX=" + axisX + " axisY=" + axisY + "\n" + "isRevertable=" + isRevertable + " isPushable=" + isPushable + "\n" + "oldTransform=" + oldTransform + "\n" + "transform=" + transform + "\n";
    }
}
